/**
 * 
 */
package it.fuesi.expired.adapters;

import android.app.Fragment;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;

import java.util.ArrayList;
import java.util.List;

import it.fuesi.expired.api.client.base.ACrudBroker;
import it.fuesi.expired.model.FindParameters;
import it.fuesi.expired.model.base.ErrorModel;
import it.fuesi.expired.model.base.IModel;
import it.fuesi.expired.model.base.ModelCollection;

/**
 * @author pascotto
 *
 */
public abstract class AbstractAdapter<T extends IModel, C extends ModelCollection<T>> extends BaseAdapter implements Filterable {

    protected static final String TAG = "AbstractAdapter";

    public static final String API_ENDPOINT = "http://172.18.205.178:7070/expired-api/";

	 protected C data;
	 private Context context;
	 private Fragment fragment;
	 private LayoutInflater inflater;

     protected Context getContext(){
         return this.context;
     }
	 
	 public AbstractAdapter(LayoutInflater inflater, C data, Context context, Fragment fragment)  {
	         this.data = data;
	         this.context=context;
	         this.fragment=fragment;
	         this.inflater = inflater;
	 }

    public void setItemCollection(C collection){
        this.data = collection;
        notifyDataSetChanged();
    }

	/* (non-Javadoc)
	 * @see android.widget.Adapter#getCount()
	 */
	@Override
	public int getCount() {
		return data != null ? data.getCount() : 0;
	}

	/* (non-Javadoc)
	 * @see android.widget.Adapter#getItem(int)
	 */
	@Override
	public Object getItem(int index) {
        if(data != null && data.getList() != null) {
            final T obj = data.getList().get(index);
            return obj;
        }
        return null;
	}

	/* (non-Javadoc)
	 * @see android.widget.Adapter#getItemId(int)
	 */
	@Override
	public long getItemId(int id) {
		return id;
	}

	/* (non-Javadoc)
	 * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
	 */
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		 View vi=convertView;
	        if(convertView==null){
	            vi = inflater.inflate(getListItemLayout(), null);
	        }
	 
	       // TextView name = (TextView)vi.findViewById(R.id.item_name); // titlee
	        
	        final T item = data.get(position);

	        final View finalView = vi;

	       // name.setText(item.get_id()); //FIXME

            drawView(vi, item);

	         return vi;
	}

    public T remove(int position){
        return data.remove(position);
    }

    public T remove(String id){
        return data.remove(id);
    }

    public void delete(int position){
        new HttpDeleteTask().execute((T) getItem(position));
    }

    protected abstract void drawView(View view, T item);

    protected abstract int getListItemLayout();

    protected abstract ACrudBroker<T,C> getClientBroker();


    public void fetch(){
       fetch(null);
    }

    public void fetch(FindParameters params){
        new HttpRequestTask().execute(params);
    }

    protected abstract boolean matchCurrentFilter(T obj, CharSequence searchText);

    @Override
    public Filter getFilter() {

        return new Filter() {

            FilterResults results;

            @Override
            protected FilterResults performFiltering(CharSequence searchText) {
                Log.d(TAG, "Filtering results: " + searchText);
                this.results = new FilterResults();

                final List<T> list = new ArrayList<T>();

                if(data != null){
                    for (T obj : data.getList()){
                        if(matchCurrentFilter(obj, searchText))
                            list.add(obj);
                    }
                }

                results.count = list.size();
                results.values = list;

                return results;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                Log.d(TAG, "Publishing Filtering results: " + filterResults.count);
                filterResults.values = this.results.values;
                filterResults.count = this.results.count;
            }
        };
    }


    private class HttpRequestTask extends AsyncTask<FindParameters, Void, C > {

        @Override
        protected C doInBackground(FindParameters... params) {
            try {

                ACrudBroker<T,C> broker = AbstractAdapter.this.getClientBroker();
                if(params != null && params.length > 0)
                    return broker.find(params[0]);
                else
                    return broker.getAll();

            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }

            return null;
        }

        @Override
        protected void onPostExecute(C items) {
            Log.d(TAG, "Received items: "+ items);
            AbstractAdapter.this.setItemCollection(items);

        }

    }

    private class HttpDeleteTask extends AsyncTask<T, Void, ErrorModel> {

        @Override
        protected ErrorModel doInBackground(T... params) {
            try {

                T item = params[0];

                ACrudBroker<T,C> broker = AbstractAdapter.this.getClientBroker();
                return broker.delete(item.get_id());

            } catch (Exception e) {
                Log.e(TAG, e.getMessage(), e);
            }

            return null;
        }

        @Override
        protected void onPostExecute(ErrorModel errorModel) {
            Log.d("MainActivity", "ErrorModel: "+ errorModel);
            if(errorModel.isSuccess()) {
                T item = AbstractAdapter.this.remove(errorModel.get_id());
                AbstractAdapter.this.notifyDataSetChanged();
            }

        }

    }


}
